package com.example.memento.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;

/**
 * 词典源配置实体
 * 管理词典数据源的配置信息
 */
@Table("dictionary_sources")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class DictionarySource {
    
    @Id(keyType = KeyType.Auto)
    private Long id;
    
    @NotBlank(message = "词典源名称不能为空")
    @Size(max = 100, message = "词典源名称长度不能超过100个字符")
    private String name;
    
    @Size(max = 500, message = "URL长度不能超过500个字符")
    private String url;
    
    @Size(max = 500, message = "下载URL长度不能超过500个字符")
    private String downloadUrl;
    
    /**
     * 下载保存路径（可选，支持多个路径，用逗号分隔）
     * 如果未配置，则使用默认路径
     * 下载时会检查每个路径的磁盘空间，随机选择有足够空间的路径
     * 示例: "data/domains,/mnt/disk1/domains,/mnt/disk2/domains"
     */
    @Size(max = 2000, message = "保存路径长度不能超过2000个字符")
    private String savePath;
    
    @NotNull(message = "启用状态不能为空")
    @Builder.Default
    private Boolean enabled = true;
    
    @Size(max = 50, message = "格式长度不能超过50个字符")
    private String format;
    
    /**
     * 下载来源（GitHub、Gitee、外网、广域网、网盘等）
     */
    private DownloadSource downloadSource;
    
    @Size(max = 1000, message = "描述长度不能超过1000个字符")
    private String description;
    
    @Size(max = 50, message = "版本长度不能超过50个字符")
    private String version;
    
    private Long fileSize;
    
    @Size(max = 100, message = "校验和长度不能超过100个字符")
    private String checksum;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdAt;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updatedAt;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastDownloadedAt;
    
    /**
     * 检查是否支持指定格式
     */
    public boolean supportsFormat(String format) {
        if (this.format == null || format == null) {
            return false;
        }
        return this.format.equalsIgnoreCase(format);
    }
    
    /**
     * 检查是否需要更新
     */
    public boolean needsUpdate(String newChecksum) {
        if (checksum == null || newChecksum == null) {
            return true;
        }
        return !checksum.equals(newChecksum);
    }
    
    /**
     * 检查是否启用
     */
    public boolean isEnabled() {
        return enabled != null && enabled;
    }
    
    /**
     * 设置创建时间戳
     * 在MyBatis-Flex中，我们需要手动调用此方法
     */
    public void onCreate() {
        createdAt = LocalDateTime.now();
        updatedAt = LocalDateTime.now();
    }
    
    /**
     * 设置更新时间戳
     * 在MyBatis-Flex中，我们需要手动调用此方法
     */
    public void onUpdate() {
        updatedAt = LocalDateTime.now();
    }
    
    /**
     * 获取文件大小的人类可读格式
     */
    public String getFormattedFileSize() {
        if (fileSize == null) {
            return "未知";
        }
        
        if (fileSize < 1024) {
            return fileSize + " B";
        } else if (fileSize < 1024 * 1024) {
            return String.format("%.1f KB", fileSize / 1024.0);
        } else if (fileSize < 1024 * 1024 * 1024) {
            return String.format("%.1f MB", fileSize / (1024.0 * 1024.0));
        } else {
            return String.format("%.1f GB", fileSize / (1024.0 * 1024.0 * 1024.0));
        }
    }
    
    /**
     * 自动检测并设置下载来源
     */
    public void detectDownloadSource() {
        if (downloadUrl != null && !downloadUrl.isEmpty()) {
            this.downloadSource = DownloadSource.detectFromUrl(downloadUrl);
        } else if (url != null && !url.isEmpty()) {
            this.downloadSource = DownloadSource.detectFromUrl(url);
        } else {
            this.downloadSource = DownloadSource.OTHER;
        }
    }
    
    /**
     * 获取下载来源代码（用于序列化）
     */
    public String getDownloadSourceCode() {
        return downloadSource != null ? downloadSource.getCode() : DownloadSource.OTHER.getCode();
    }
    
    /**
     * 设置下载来源代码（用于反序列化）
     */
    public void setDownloadSourceCode(String code) {
        this.downloadSource = DownloadSource.fromCode(code);
    }
}
